package com.hunyuan.player;

import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;

/**
 * Created by hunyuan on 2017/1/18.
 */

public class PlaybackManager implements Playback.Callback {

    private static final String TAG = PlaybackManager.class.getSimpleName();

    private MediaSessionCallback mMediaSessionCallback;
    private PlaybackServiceCallback mServiceCallback;
    private QueueManager mQueueManager;
    private Playback mPlayback;

    public PlaybackManager(PlaybackServiceCallback serviceCallback,
                           QueueManager queueManager,
                           Playback playback) {
        mServiceCallback = serviceCallback;
        mQueueManager = queueManager;
        mPlayback = playback;
        mMediaSessionCallback = new MediaSessionCallback();
    }

    public MediaSessionCompat.Callback getMediaSessionCallback() {
        return mMediaSessionCallback;
    }

    public Playback getPlayback() {
        return mPlayback;
    }

    @Override
    public void onCompletion() {
        if (mQueueManager.skipQueuePosition(1)) {
            // 播放下一首
            handlePlayRequest();
            mQueueManager.updateMetadata();
        } else {
            // 停止播放
            handleStopRequest(null);
        }
    }


    @Override
    public void onPlaybackStatusChanged(int state) {
        //更改状态
        updatePlaybackState(null);
    }

    @Override
    public void onError(String error) {
        //更改状态显示错误状态
        updatePlaybackState(error);
    }

    @Override
    public void setCurrentMediaId(String mediaId) {
        //设置当前音乐
        mQueueManager.setQueueFromMusic(mediaId);
    }

    /**
     * 处理开始播放请求
     */
    public void handlePlayRequest() {
        Log.d(TAG, "handlePlayRequest: mState=" + mPlayback.getState());
        MediaSessionCompat.QueueItem currentMusic = mQueueManager.getCurrentMusic();
        if (currentMusic != null) {
            mServiceCallback.onPlaybackStart();
            mPlayback.play(currentMusic);
        }
    }

    /**
     * 处理停止播放请求
     *
     * @param withError 发生意外的错误信息。错误信息会被设置到PlaybackState中并对于MediaController可见
     */
    public void handleStopRequest(String withError) {
        Log.d(TAG, "handleStopRequest: mState=" + mPlayback.getState());
        mPlayback.stop(true);
        mServiceCallback.onPlaybackStop();
        updatePlaybackState(withError);
    }

    /**
     * 处理暂停播放请求
     */
    public void handlePauseRequest() {
        Log.d(TAG, "handlePauseRequest: mState=" + mPlayback.getState());
        if (mPlayback.isPlaying()) {
            mPlayback.pause();
            mServiceCallback.onPlaybackStop();
        }
    }

    /**
     * 更新当前播放器的状态，可以显示一条错误
     *
     * @param error 如果不为空，错误信息可以被展示给用户
     */
    public void updatePlaybackState(String error) {
        Log.d(TAG, "updatePlaybackState");
        long position = PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN;
        if (mPlayback != null && mPlayback.isConnected()) {
            position = mPlayback.getCurrentStreamPosition();
        }

        //noinspection ResourceType
        PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder().setActions(getAvailableActions());

        int state = mPlayback.getState();

        // 如果error不为空，设置错误信息
        if (error != null) {
            stateBuilder.setErrorMessage(error);
            state = PlaybackStateCompat.STATE_ERROR;
        }
        //noinspection ResourceType
        stateBuilder.setState(state, position, 1.0f, SystemClock.elapsedRealtime());

        // 如果当前音乐不为空，设置QueueId
        MediaSessionCompat.QueueItem currentMusic = mQueueManager.getCurrentMusic();
        if (currentMusic != null) {
            stateBuilder.setActiveQueueItemId(currentMusic.getQueueId());
        }

        mServiceCallback.onPlaybackStateUpdated(stateBuilder.build());

        if (state == PlaybackStateCompat.STATE_PLAYING || state == PlaybackStateCompat.STATE_PAUSED) {
            mServiceCallback.onNotificationRequired();
        }
    }

    private long getAvailableActions() {
        long actions =
                PlaybackStateCompat.ACTION_PLAY |
                        PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID |
                        PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH |
                        PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
                        PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
        if (mPlayback.isPlaying()) {
            actions |= PlaybackStateCompat.ACTION_PAUSE;
        }
        return actions;
    }

    private class MediaSessionCallback extends MediaSessionCompat.Callback {
        @Override
        public void onPlay() {
            Log.d("onPlay", "play");
            if (mQueueManager.getCurrentMusic() == null) {
                mQueueManager.setCurrentQueueItem(0);
            }
            handlePlayRequest();
        }

        @Override
        public void onSkipToQueueItem(long queueId) {
            Log.d("OnSkipToQueueItem", queueId + "");
            mQueueManager.setCurrentQueueItem(queueId);
            mQueueManager.updateMetadata();
        }

        @Override
        public void onSeekTo(long position) {
            Log.d("onSeekTo", position + "");
            mPlayback.seekTo((int) position);
        }

        @Override
        public void onPlayFromMediaId(String mediaId, Bundle extras) {
            Log.d("onPlayFromMediaId", mediaId);
            mQueueManager.setQueueFromMusic(mediaId);
            handlePlayRequest();
        }

        @Override
        public void onPause() {
            Log.d("onPause", "onPause");
            handlePauseRequest();
        }

        @Override
        public void onStop() {
            Log.d("onStop", "onStop");
            handleStopRequest(null);
        }

        @Override
        public void onSkipToNext() {
            Log.d("onSkipToNext", "onSkipToNext");
            if (mQueueManager.skipQueuePosition(1)) {
                handlePlayRequest();
            } else {
                handleStopRequest("不能跳转下一首");
            }
            mQueueManager.updateMetadata();
        }

        @Override
        public void onSkipToPrevious() {
            Log.d("onSkipToPrevious", "onSkipToPrevious");
            if (mQueueManager.skipQueuePosition(-1)) {
                handlePlayRequest();
            } else {
                handleStopRequest("不能跳转上一首");
            }
            mQueueManager.updateMetadata();
        }

        @Override
        public void onCustomAction(@NonNull String action, Bundle extras) {
            Log.d("onCustomAction", action);
        }

        @Override
        public void onPlayFromSearch(final String query, final Bundle extras) {
            Log.d("onPlayFromSearch", query);
        }
    }

    public interface PlaybackServiceCallback {
        void onPlaybackStart();

        void onNotificationRequired();

        void onPlaybackStop();

        void onPlaybackStateUpdated(PlaybackStateCompat newState);
    }
}
